package tgc.edu.examxy.web.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import tgc.edu.examxy.custom.AjaxResult;
import tgc.edu.examxy.custom.DataGridParam;
import tgc.edu.examxy.custom.DataGridUtils;
import tgc.edu.examxy.custom.TimeUtils;
import tgc.edu.examxy.entity.CurriculumPlan;
import tgc.edu.examxy.entity.Evaluation;
import tgc.edu.examxy.entity.EvaluationRule;
import tgc.edu.examxy.entity.EvaluationXz;
import tgc.edu.examxy.entity.Student;
import tgc.edu.examxy.entity.TeachingProgramme;
import tgc.edu.examxy.security.User2;
import tgc.edu.examxy.service.CurriculumPlanService;
import tgc.edu.examxy.service.EvaluationRuleService;
import tgc.edu.examxy.service.EvaluationService;
import tgc.edu.examxy.service.EvaluationXzService;
import tgc.edu.examxy.service.StudentService;
import tgc.edu.examxy.service.TeachingProgrammeService;
import tgc.edu.examxy.web.form.EvaluationRuleForm;
import tgc.edu.examxy.web.form.EvaluationgradeForm;
import tgc.edu.examxy.web.form.StudentForm;

/***
 * 课程评价
 * 
 * @author 936642284
 *
 */
@Controller
@RequestMapping(value = "/courseEvaluation")
public class CourseEvaluationController {
	@Autowired
	private StudentService studentservice;
	@Autowired
	private EvaluationRuleService erservice;
	@Autowired
	private CurriculumPlanService teachingservice;
	@Autowired
	private EvaluationXzService exService;
	@Autowired
	private EvaluationService Evaluationservice;

	/***
	 * 显示
	 * 
	 * @return
	 */
	@RequestMapping(value = "/manage")
	private String manage() {
		SecurityContext ctx = SecurityContextHolder.getContext();
		Authentication auth = ctx.getAuthentication();
		User2 user = (User2) auth.getPrincipal();
		Student student = studentservice.findByUsername(user.getUsername());
		if(user.getUsername()==null||user.getUsername()=="") {
			return "courseEvaluation/manage";
		}
		// 根据班级 查找出所有
		List<CurriculumPlan> teachings = teachingservice.findByTbClass(student.getTbClass());
		int rulesort = 2;
		for (CurriculumPlan t : teachings) {
			EvaluationRule ers = erservice.findByStudentIdAndTeachingProgrammeId(student.getId(), t.getId());
			if (ers == null && student.getId() != null && t.getId() != null) {
				EvaluationRule erentity = new EvaluationRule();
				erentity.setStudentId(student.getId());
				erentity.setTeachingProgrammeId(t.getId());
				erentity.setTbClassId(t.getTbClass().getId());
				erentity.setTeacherId(t.getTeacher().getId());
				erentity.setStudentname(student.getName());
				erentity.setStudentusername(student.getUsername());
				erentity.setTbClassName(t.getTbClass().getName());
				erentity.setTbClassTeachername(t.getTbClass().getTeacherId().getName());
				erentity.setTbCurriculumCourseName(t.getCurriculum().getCourseName());
				erentity.setTeacherName(t.getTeacher().getName());
				erentity.setIsUsed(true);
				erentity.setTime(t.getFinishttime());
				/** 查看状态 **/
				Integer comparisontime = TimeUtils.Comparisontime(t.getFinishttime());
				erentity.setIsevaluate(comparisontime);
				
				int rulesort2 = TimeUtils.rulesort(t.getFinishttime(),rulesort);
				erentity.setRulesort(rulesort2);
				erentity.setTeachingProgrammeType("TYPE_ONE");
				erservice.save(erentity);
			}else {
				//改变状态
				if(ers.getIsevaluate()!=2) {
					Integer comparisontime = TimeUtils.Comparisontime(t.getFinishttime());
					ers.setIsevaluate(comparisontime);
					int rulesort2 = TimeUtils.rulesort(t.getFinishttime(),rulesort);
					ers.setRulesort(rulesort2);
					erservice.save(ers);
				}
			}
			rulesort++;
		}
		return "courseEvaluation/manage";
	}

	/***
	 * 显示需要评价的老师
	 * 
	 * @param param
	 * @param form
	 * @return
	 */
	@RequestMapping(value = "/page")
	@ResponseBody
	public Object page(DataGridParam param, EvaluationRuleForm form) {
		Sort sort = Sort.by("rulesort");
		Pageable pageable = param.getPageable(sort);
		Specification<EvaluationRule> spec = buildSpec(form);
		Page<EvaluationRule> page = erservice.findAll(spec, pageable);
		return DataGridUtils.buildResult(page);
	}

	private Specification<EvaluationRule> buildSpec(EvaluationRuleForm form) {
		SecurityContext ctx = SecurityContextHolder.getContext();
		Authentication auth = ctx.getAuthentication();
		User2 user = (User2) auth.getPrincipal();
		Student students = studentservice.findByUsername(user.getUsername());

		Specification<EvaluationRule> specification = new Specification<EvaluationRule>() {

			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<EvaluationRule> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if (students != null) {
					Predicate name = cb.equal(root.get("studentId"), students.getId());
					rules.add(name);
				}
				if (students != null) {
					Predicate name = cb.equal(root.get("tbClassId"), students.getTbClass().getId());
					rules.add(name);
				}
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		if(StringUtils.hasText(form.getSearch())) {
			Specification<EvaluationRule> specification1= new Specification<EvaluationRule>() {

				private static final long serialVersionUID = 1L;

				@Override
				public Predicate toPredicate(Root<EvaluationRule> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
					HashSet<Predicate> rules=new HashSet<>();
					String search = form.getSearch();
					
					
					if(StringUtils.hasText(search)) {
						rules.add(cb.like(root.get("tbCurriculumCourseName"), "%"+search+"%"));
					}
					if(StringUtils.hasText(search)) {
						rules.add(cb.like(root.get("teacherName"), "%"+search+"%"));
					}
					if(StringUtils.hasText(search)) {
						Boolean isisevaluate;
						if(search.equals("已评价")) {
							isisevaluate = true;
							rules.add(cb.equal(root.get("isevaluate"), isisevaluate));
						}else if(search.equals("未评价")){
							isisevaluate = false;
							rules.add(cb.equal(root.get("isevaluate"), isisevaluate));
						}
					}
					return cb.or(rules.toArray(new Predicate[rules.size()]));
				}
				
			};
			return specification.and(specification1);
		}else {
			return specification;
		}
	}

	/***
	 * 查看
	 * 
	 * @param uuid
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/toview")
	private String Toview(String uuid, ModelMap map) {
		map.put("uuid", uuid);
		Specification<Evaluation> spec = buildSpec(uuid);
		List<Evaluation> page = Evaluationservice.findAll(spec);
		for (int i = 0; i < page.size(); i++) {
			page.get(i).setSum(i);
		}
		map.put("evaluation", page.get(0).getEvaluationRule().getEvaluation());
		map.put("suggest", page.get(0).getEvaluationRule().getSuggest());
		map.put("page", page);
		map.put("max", page.size());
		return "courseEvaluation/readonly";
	}
	
	/****
	 * 评价
	 * 
	 * @param uuid
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/evaluation")
	private String evaluation(String uuid, ModelMap map) {
		EvaluationRule rules = erservice.findById(UUID.fromString(uuid));
		if (rules != null) {
			List<EvaluationXz> xzentity = exService.findByType(rules.getTeachingProgrammeType());
			for (EvaluationXz exz : xzentity) {
				Evaluation evaluations = Evaluationservice.findByEvaluationRuleAndEvaluationXzId(rules, exz.getId());
				if (evaluations == null) {
					Evaluation Evaluationentitys = new Evaluation();
					Evaluationentitys.setEvaluationRule(rules);
					Evaluationentitys.setEvaluationXzId(exz.getId());
					Evaluationentitys.setType(exz.getType());
					Evaluationentitys.setExplain(exz.getExplain());
					Evaluationentitys.setSystem(exz.getSystem());
					Evaluationentitys.setWeight(exz.getWeight());
					Evaluationservice.save(Evaluationentitys);
				}
			}
		}
		map.put("name", rules.getTbCurriculumCourseName());
		map.put("uuid", uuid);
		Specification<Evaluation> spec = buildSpec(uuid);
		List<Evaluation> page = Evaluationservice.findAll(spec);
		for (int i = 0; i < page.size(); i++) {
			page.get(i).setSum(i);
		}
		map.put("page", page);
		map.put("max", page.size());
		return "courseEvaluation/operation";
	}

	/***
	 * 安全查询
	 * 
	 * @param uuid
	 * @return
	 */
	private Specification<Evaluation> buildSpec(String uuid) {
		SecurityContext ctx = SecurityContextHolder.getContext();
		Authentication auth = ctx.getAuthentication();
		User2 user = (User2) auth.getPrincipal();
		Student students = studentservice.findByUsername(user.getUsername());

		Specification<Evaluation> specification = new Specification<Evaluation>() {

			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<Evaluation> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if (students != null) {
					Predicate name = cb.equal(root.get("evaluationRule").get("studentId"), students.getId());
					rules.add(name);
				}
				if (uuid != null) {
					Predicate name = cb.equal(root.get("evaluationRule").get("id"), UUID.fromString(uuid));
					rules.add(name);
				}
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};

		return specification;
	}

	@RequestMapping(value = "/postnumber")
	@ResponseBody
	private Object postsave(String uuid, Integer numbers) {
		try {

			Evaluation findById = Evaluationservice.findById(UUID.fromString(uuid));
			if (numbers <= 5 && numbers >= 1 && findById != null) {
				findById.setPostgrade(numbers);
				Evaluationservice.save(findById);
				return new AjaxResult(true, "评价" + numbers + "星");
			}
		} catch (Exception e) {
			return new AjaxResult(false, "评价失败" + numbers);
		}

		return new AjaxResult(false, "评价失败" + numbers);
	}

	@RequestMapping(value = "/evaluationgradsave")
	@ResponseBody
	private Object evaluationgradsave(@RequestBody Object map) {
		Map<String,List<String>> hashMap = new HashMap<String,List<String>>();
		hashMap = (Map<String, List<String>>) map;
		List<String> result = hashMap.get("result");
		System.out.println(result.toString());
		List<String> resultuuid = hashMap.get("resultuuid");
		double sum = 0 ;
		EvaluationRule eevaluationRule = new EvaluationRule();
		for (int i = 0; i < result.size(); i++) {
			Evaluation eva = Evaluationservice.findById(UUID.fromString(resultuuid.get(i)));
			Integer it = new Integer(result.get(i));
			if (it == eva.getPostgrade()) {
				eva.setGrade(it);
				Evaluationservice.save(eva);
			} else {
				eva.setPostisno("POST值和保存时出现问题，以保存时为准！");
				eva.setGrade(it);
				Evaluationservice.save(eva);
			}
			/** 算最后老师获得的分数 **/
			sum += it * eva.getWeight();
			eevaluationRule  = eva.getEvaluationRule();
		}
		/** 从map取出课程点评和建议和修改评价状态 **/
		if (eevaluationRule != null) {
			List<String> evaluation = hashMap.get("evaluation");
			eevaluationRule.setEvaluation(evaluation.get(0));
			
			List<String> suggest = hashMap.get("suggest");
			eevaluationRule.setSuggest(suggest.get(0));
			eevaluationRule.setGrads(sum);
			eevaluationRule.setRulesort(4000);
			eevaluationRule.setIsevaluate(2);
			erservice.save(eevaluationRule);
		}
		/** 留作参考 **/
		/*for(Entry<String, Form1> entry:hashMap.entrySet()) {
			value=entry.getValue();
			Form1 form1 = hashMap.get(entry.getKey());
			System.out.println(form1.getResult()+"=====result");
			System.out.println(form1.getAaa()+"=====aaaa");
		}*/
		//System.out.println(value.getResult());
		

		return new AjaxResult(true, "评价成功");
	}
}
